/**
 * 两点通视的组件，
 * 主要步骤：
 * （1）设置视高
 * （2）设置起点终点，
 * （3）从起点发射沿着起点终点方向的射线，找到碰撞点
 * （4）根据碰撞点分段，前部分可视域绿色表示，盲区红色线表示
 */
import * as Cesium from 'cesium';
import mouseHelper from "../../MouseHelper";
let  handler:any=null;
let _viewer: any = {};
class TwoPointView{
  viewPoint:any;
  entities:any;
    constructor() {
      //视点
      this.viewPoint=null;
      //两个视点的数组
      this.entities=[];
    }

  /**
   * 开始两点通视
   * @param viewer
   * @param height  观察点高度，也可以当做视点
   */
    startAnalysis(viewer:any,height:number,tipOffset:any){
      _viewer=viewer;
      handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
      let _this=this;
      //左键点击创建视点
      handler.setInputAction(function(evt: any) {
        let car3 = innerFun.getCar3Position(viewer,evt.position);
        _this.viewPoint=new Cesium.Cartesian3(car3.x, car3.y, car3.z+height);
        let entity=  _this.creaPointEntity(car3, "#008000");
        _this.entities.push(entity)
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);


      handler.setInputAction(function(evt: any) {
        //屏幕坐标
        let car2Position=evt.endPosition;
        if(mouseHelper.helperTips){
          mouseHelper.updateHelper(car2Position, '左击设置起点,右击设置终点',tipOffset);
        }else{
          mouseHelper.createHelper(car2Position, '左击设置起点,右击设置终点',tipOffset);
        }

      }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    //鼠标右键点击事件--创建终点
    handler.setInputAction(function(evt:any)  {
      let car3 = innerFun.getCar3Position(viewer,evt.position);
      if(_this.viewPoint){
      let entity=  _this.creaPointEntity(car3, "#FF0000");
        _this.entities.push(entity);
        _this.analysisVisible(_this.viewPoint,car3);
      }
      _this.endDrawing();
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
    }

  /**
   * 结束绘制
   */
  endDrawing() {
    if(handler){
      handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
      handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
      handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
    }
    mouseHelper.removeHelper()
  }

  /**
   * 清除绘制的Graphic
   */
  clearEntities() {
    this.endDrawing();
    if(this.entities.length>0){
      this.entities.forEach((item:any)=>{
        _viewer.entities.remove(item)
      })
    }
    //视点
    this.viewPoint=null;
    //两个视点的数组
    this.entities=[];
  }


  /**
   * 进行分析
   * @param startPosition
   * @param endPosition
   */
  // * 通视分析
  analysisVisible (startPosition:any, endPosition:any) {
    // * 计算射线的方向
    let direction = Cesium.Cartesian3.normalize(
      Cesium.Cartesian3.subtract(
        endPosition,
        startPosition,
        new Cesium.Cartesian3()
      ),
      new Cesium.Cartesian3()
    );
    // 建立射线
    let ray = new Cesium.Ray(startPosition, direction);
    let result = _viewer.scene.pickFromRay(ray); // 计算交点
    if (result !== undefined && result !== null) {
     let entityOne= this.createPolyline(result.position, startPosition,"#008000"); // 可视
     let entityTwo= this.createPolyline(result.position, endPosition, "#FF0000"); // 不可视
      this.entities.push(entityOne);
      this.entities.push(entityTwo)
    } else {
     let entity= this.createPolyline(startPosition, endPosition, "#008000");
     this.entities.push(entity);
    }
  }

   createPolyline(startPosition:any,endPosition:any,color:string){
    let entity= _viewer.entities.add({
       polyline: {
         positions: [startPosition, endPosition],
         width: 1,
         material:  Cesium.Color.fromCssColorString(color),
         depthFailMaterial: Cesium.Color.fromCssColorString(color)
       }
     });
    return entity;
   }
    creaPointEntity(car3:any,color:string){
      let entity=_viewer.entities.add({
        position: car3,
        point: {
          pixelSize: 10,
          color: Cesium.Color.fromCssColorString(color)
        }
      })
      return entity;
    }


}
export default  new TwoPointView();

/**
 * 内部的公共的方法
 */
const innerFun = {
  /**
   * 鼠标的事件获取当前的点击位置的笛卡尔坐标
   * @param position 鼠标点击之后的evt.position
   */
  getCar3Position: function(viewer:any,position: any) {
    let car3: any = null;
    let pick = viewer.scene.pick(position);
    if (viewer.scene.globe.depthTestAgainstTerrain) {
      if (Cesium.defined(pick)) {//获取到了pick
        car3 = viewer.scene.pickPosition(position);
      } else {
        let ray = viewer.camera.getPickRay(position);//获取一条射线
        car3 = viewer.scene.globe.pick(ray, viewer.scene);
      }
    } else {
      car3 = viewer.scene.camera.pickEllipsoid(position, viewer.scene.globe.ellipsoid);
    }
    return car3;
  }
};
